package com.rzjm.api.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.rzjm.api.config.RequestDataHelper;
import com.rzjm.api.dao.ChargerMapper;
import com.rzjm.api.dao.ChargerOrderMapper;
import com.rzjm.api.dao.ChargerPortRecordMapper;
import com.rzjm.api.entity.*;
import com.rzjm.api.exception.TransactionalException;
import com.rzjm.api.netty.charger.ClientSocket;
import com.rzjm.api.netty.charger.SocketPool;
import com.rzjm.api.pay.wxpay.WxAppPay;
import com.rzjm.api.service.*;
import com.rzjm.api.util.*;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;

/**
 *  充电上传记录Service业务层处理
 *
 * @author ruoyi
 * @date 2022-05-07
 */
@Service
public class ChargerPortRecordServiceImpl extends BaseServiceImpl<ChargerPortRecordMapper, ChargerPortRecord> implements ChargerPortRecordService {

    @Resource
    private ChargerPortRecordMapper portRecordMapper;
    @Resource
    private ChargerOrderMapper chargerOrderMapper;
    @Resource
    private ChargerOrderService chargerOrderService;
    @Resource
    private ChargerPortService chargerPortService;
    @Resource
    private ParameterService parameterService;
    @Resource
    private ChargerPowerRoleService powerRoleService;
    @Resource
    private WxTemplateService wxTemplateService;
    @Resource
    private ChargerMapper chargerMapper;
    @Resource
    private SplitAccountService splitAccountService;
    @Resource
    private SplitAccountRecordService splitAccountRecordService;
    @Resource
    private PlatformPayService platformPayService;

    @Resource
    protected RedisTemplate<String, Object> redisTemplate;


    @Value("${web.wx_refund_notify_url}")
    private String wx_refund_notify_url;//微信支付的回调地址

    @Value("${web.appid}")
    private String appid;
    @Value("${web.secret}")
    private String secret;
    @Value("${web.mch_id}")
    private String mch_id;
    @Value("${web.api_key}")
    private String api_key;
    @Value("${web.keyPath}")
    private String keyPath;//微信支付的回调地址

    @Override
    @Transactional
    public int addRecord(Charger charger,int portIndex, String[] dataArray,String data,String orderNum) {
        int ret = 0;
        try{
//            Parameter parameter = parameterService.getParameterById(1);
            //状态,电压,电流,订单号,功率
            //0,   1,   2,  3,    4
            ChargerPortRecord portRecord = new ChargerPortRecord();
            portRecord.setOrderNum(orderNum);
            portRecord.setChargerId(charger.getId());
            portRecord.setCreateTime(new Date());
            portRecord.setChargerNum(charger.getChargerNum());
            portRecord.setChargerSn(charger.getChargerSn());
            portRecord.setChargerPort(portIndex);
            portRecord.setOrderNo(dataArray[3]);
            portRecord.setDataStr(data);
            //电流
            if(StrUtil.isNotEmpty(dataArray[2])){
                double electricCurrent = MathUtil.getDoubleUp(Double.parseDouble(dataArray[2]) / 1000);
                portRecord.setElectricCurrent(electricCurrent);
            }
            //电压
            if(StrUtil.isNotEmpty(dataArray[1])){
                double voltage = MathUtil.getDoubleUp(Double.parseDouble(dataArray[1]) / 100);
                portRecord.setVoltage(voltage);
            }
            // 功率
            if(StrUtil.isNotEmpty(dataArray[4])){
                double power = MathUtil.getDoubleUp(portRecord.getElectricCurrent().doubleValue() * portRecord.getVoltage().doubleValue());
                if(charger.getAddPower()!=null && charger.getAddPower() > 0){
                    power += charger.getAddPower();
                }
                portRecord.setPower(power);
            }

            String key = "charger_" + charger.getChargerSn();
            charger.setLastOnlineTime(new Date());
            redisTemplate.opsForHash().put(key, key, JSONUtil.toJsonStr(charger));
            chargerMapper.updateById(charger);

            //带订单号的信条数据
            if(StrUtil.isNotEmpty(dataArray[3])) {
                ChargerOrder chargerOrder = chargerOrderMapper.selectOneByColumn("order_no",dataArray[3]);
                if(chargerOrder != null){
                    Map<String,Object> map = new HashMap<>();
                    map.put("charger_port_record", chargerOrder.getRecordTableName());
                    RequestDataHelper.setRequestData(map);

                    portRecord.setUserId(chargerOrder.getUserId());
                    int useMinutes = chargerOrder.getUseMinutes();
                    useMinutes = useMinutes + 1;
                    chargerOrder.setUseMinutes(useMinutes);

                    chargerOrder.setLastActiveTime(new Date());

                    //已经充电的度数
                    double chargerCapacity = getChargerCapacity(chargerOrder);
//                    System.out.println("当前已用用电量：" + chargerCapacity);
                    chargerOrder.setUseChargerCapacity(MathUtil.getDoubleUp(chargerCapacity));
                    //当前已经使用的钱
                    double useTotalPrice = 0d;

                    if(chargerOrder.getChargerRoleType() == 0){//按照功率来计算价格
                        useTotalPrice = getTotalPriceByCharger(chargerOrder);
                    }else if(chargerOrder.getChargerRoleType() == 1){//按照用电度数来计算价格
                        useTotalPrice = getTotalPriceByChargerType1(chargerOrder,chargerCapacity);
                    }else if(chargerOrder.getChargerRoleType() == 2){//按照充电时间 来计算价格
                        useTotalPrice = getTotalPriceByChargerType2(chargerOrder);
                    }
                    int buyMinutes = chargerOrder.getBuyMinutes().intValue();

//                    useTotalPrice = MathUtil.getDoubleUp(useTotalPrice);
                    chargerOrder.setUsePrice(new BigDecimal(useTotalPrice));
                    double everyMin =  1.00 / 60.00 / 1000 *  portRecord.getPower();
                    portRecord.setChargerCapacity(new BigDecimal(everyMin));

                    double maxPower = 650d;
                    if(charger.getMaxPower() != null){
                        maxPower = charger.getMaxPower().doubleValue();
                    }

                    //当前功率下的单价
                    portRecord.setPowerRoleId(0);
                    portRecord.setSinglePrice(new BigDecimal(0));
                    ChargerPowerRole powerRole = powerRoleService.getSinglePriceByChargerPower(charger, portRecord.getPower().doubleValue());
                    if(powerRole != null){
                        portRecord.setPowerRoleId(powerRole.getId());
                        portRecord.setSinglePrice(powerRole.getSinglePriceHour());
                    }

                    //判断充电功率 是否超限
                    if(portRecord.getPower().doubleValue() > maxPower) {
                        List<ClientSocket> clientSocketList = SocketPool.getClientByDeviceNum(chargerOrder.getDeviceSn());
                        for (ClientSocket clientSocket : clientSocketList) {
                            if (StrUtil.isNotEmpty(clientSocket.getTerminalNum()) && !clientSocket.getTerminalNum().equals("null")) {
                                //结束充电命令  05
                                //端口号，订单号,故障信息（一个字节）
                                String orderData = String.format("%02d", chargerOrder.getDevicePointIndex());
                                String orderParam = "MS05" + chargerOrder.getDeviceSn() + orderData + "ME";
                                System.out.println("结束充电命令: " + orderParam);
                                clientSocket.getChannel().writeAndFlush(orderParam);
                            }
                        }
                        chargerOrder.setChargerState(2);
                        portRecord.setRemark("充电功率超过允许的最大功率，停止充电");
                        chargerOrder.setRemark("充电功率超过允许的最大功率，停止充电");
                    }
                    //判断订单是否已经停止
                    //订单状态 0 - 未支付   1 - 支付中  2 - 已支付  3 - 充电中  4 - 已发起退款  5 - 退款完成  6 - 退款失败  7 - 订单已完成（结束） 8 -  订单取消
                    else if(chargerOrder.getStatus() > 3){
                        List<ClientSocket> clientSocketList = SocketPool.getClientByDeviceNum(chargerOrder.getDeviceSn());
                        for (ClientSocket clientSocket : clientSocketList) {
                            if (StrUtil.isNotEmpty(clientSocket.getTerminalNum()) && !clientSocket.getTerminalNum().equals("null")) {
                                //结束充电命令  05
                                //端口号，订单号,故障信息（一个字节）
                                String orderData = String.format("%02d", chargerOrder.getDevicePointIndex());
                                String orderParam = "MS05" + chargerOrder.getDeviceSn() + orderData + "ME";
                                System.out.println("结束充电命令: " + orderParam);
                                clientSocket.getChannel().writeAndFlush(orderParam);
                            }
                        }
                        //停止充电  充电结束
                        //充电状态 0 - 未充电 1 - 充电中 2 - 发起结束充电命令   3 - 充电已完成
                        chargerOrder.setChargerState(2);
                        portRecord.setRemark("订单已停止");
                        chargerOrder.setRemark("订单已停止");
                    }
                    /////////////////////余额不足，停止充电///////////////////
                    //如果是超过了当前支付的费用 要停止充电
                    else if(chargerOrder.getChargerRoleType() == 0 &&  useTotalPrice >= chargerOrder.getPayPrice().doubleValue()){
                        System.out.println("购买 时间   余额不足，结束充电");
                        List<ClientSocket> clientSocketList = SocketPool.getClientByDeviceNum(chargerOrder.getDeviceSn());
                        for (ClientSocket clientSocket : clientSocketList) {
                            if (StrUtil.isNotEmpty(clientSocket.getTerminalNum()) && !clientSocket.getTerminalNum().equals("null")) {
                                //结束充电命令  05
                                //端口号，订单号,故障信息（一个字节）
                                String orderData = String.format("%02d", chargerOrder.getDevicePointIndex());
                                String orderParam = "MS05" + chargerOrder.getDeviceSn() + orderData + "ME";
                                System.out.println("结束充电命令: " + orderParam);
                                clientSocket.getChannel().writeAndFlush(orderParam);
                            }
                        }
                        //停止充电  充电结束
                        //充电状态 0 - 未充电 1 - 充电中 2 - 发起结束充电命令   3 - 充电已完成
                        chargerOrder.setChargerState(2);
                        portRecord.setRemark("购买时间余额不足，结束充电");
                        chargerOrder.setRemark("购买时间余额不足，结束充电");
                    }
                    /////////////////////余额不足，停止充电///////////////////
                    //如果是超过了当前支付的费用 要停止充电
                    //判断度数， 已使用的是否超过购买的度数
                    else if(chargerOrder.getChargerRoleType() == 1 &&  chargerCapacity >= chargerOrder.getBuyChargerCapacity()){
//                        System.out.println("当前已用用电量：" + chargerCapacity + " ==   购买用电量" + chargerOrder.getBuyChargerCapacity());

                        System.out.println("购买用电量 余额不足，结束充电");
                        if(chargerCapacity == 1.26 && chargerOrder.getBuyChargerCapacity() == 1.28){
                            chargerOrder.setUseChargerCapacity(1.28);
                        }
                        List<ClientSocket> clientSocketList = SocketPool.getClientByDeviceNum(chargerOrder.getDeviceSn());
                        for (ClientSocket clientSocket : clientSocketList) {
                            if (StrUtil.isNotEmpty(clientSocket.getTerminalNum()) && !clientSocket.getTerminalNum().equals("null")) {
                                //结束充电命令  05
                                //端口号，订单号,故障信息（一个字节）
                                String orderData = String.format("%02d", chargerOrder.getDevicePointIndex());
                                String orderParam = "MS05" + chargerOrder.getDeviceSn() + orderData + "ME";
                                System.out.println("结束充电命令: " + orderParam);
                                clientSocket.getChannel().writeAndFlush(orderParam);
                            }
                        }
                        //停止充电  充电结束
                        //充电状态 0 - 未充电 1 - 充电中 2 - 发起结束充电命令   3 - 充电已完成
                        chargerOrder.setChargerState(2);
                        portRecord.setRemark("购买用电量余额不足，结束充电");
                        chargerOrder.setRemark("购买用电量余额不足，结束充电");
                    }
                    // 按照充电时间来算   购买的时间数  和 已经使用的 时间数
                    else if(chargerOrder.getChargerRoleType() == 2 && useMinutes >= buyMinutes){
                        List<ClientSocket> clientSocketList = SocketPool.getClientByDeviceNum(chargerOrder.getDeviceSn());
                        for (ClientSocket clientSocket : clientSocketList) {
                            if (StrUtil.isNotEmpty(clientSocket.getTerminalNum()) && !clientSocket.getTerminalNum().equals("null")) {
                                //结束充电命令  05
                                //端口号，订单号,故障信息（一个字节）
                                String orderData = String.format("%02d", chargerOrder.getDevicePointIndex());
                                String orderParam = "MS05" + chargerOrder.getDeviceSn() + orderData + "ME";
                                System.out.println("结束充电命令: " + orderParam);
                                clientSocket.getChannel().writeAndFlush(orderParam);
                            }
                        }
                        //停止充电  充电结束
                        //充电状态 0 - 未充电 1 - 充电中 2 - 发起结束充电命令   3 - 充电已完成
                        chargerOrder.setChargerState(2);
                        portRecord.setRemark("充电时间已到，结束充电");
                        chargerOrder.setRemark("充电时间已到，结束充电");
                    }
                    else{
                        //当前是正常继续进行
                        portRecord.setRemark("继续充电");

                        Date startChargerTime = chargerOrder.getStartChargerTime();
                        if(startChargerTime == null){
                            if(chargerOrder.getPayTime() != null){
                                startChargerTime = DateUtil.getAfterSecondsByOld(chargerOrder.getPayTime(),5);
                                chargerOrder.setStartChargerTime(startChargerTime);
                            }else{
                                startChargerTime = DateUtil.getAfterSecondsByOld(chargerOrder.getCreateTime(),20);
                                chargerOrder.setStartChargerTime(startChargerTime);
                            }
                        }
                        //{天, 时, 分, 秒}
                        long[] times = DateUtil.getDistanceTimes(startChargerTime,new Date());
                        //充电超过1小时20分钟 并且 功率小于50W的情况下 判断涓流
                        if(times[1] > 0 && portRecord.getPower() < 50){
                            //判断涓流算法
                            int lastLimitMin = 239;
                            if(powerRole!=null && powerRole.getLimitMin() !=null && powerRole.getLimitMin() > 0){
                                lastLimitMin = powerRole.getLimitMin();
                            }

                            List<Double> powerList = getAllRecordPowers(chargerOrder,lastLimitMin);
                            powerList.add(portRecord.getPower());
                            String ss = "";
                            for (Double d : powerList){
                                ss += d+ ",";
                            }
                            portRecord.setSlopePoints(ss);
                            double slope = MathUtil.getPowerSlope(powerList);
                            portRecord.setSlope(slope);
//                            System.out.println("最后60条记录斜率：" + slope);

                            List<Double> powerListLast10 = getAllRecordPowers(chargerOrder,29);
                            powerListLast10.add(portRecord.getPower());
                            String ss10 = "";
                            for (Double d : powerListLast10){
                                ss10 += d+ ",";
                            }
                            portRecord.setSlopePointsTen(ss10);
                            double slope10 = MathUtil.getPowerSlope(powerListLast10);
                            portRecord.setSlopeLastTen(slope10);
//                            System.out.println("最后10条记录斜率：" + slope10);

                            //已进入 涓流状态
                            if(slope <= 0.15 && slope10 <= 0.15){
                                List<ClientSocket> clientSocketList = SocketPool.getClientByDeviceNum(chargerOrder.getDeviceSn());
                                for (ClientSocket clientSocket : clientSocketList) {
                                    if (StrUtil.isNotEmpty(clientSocket.getTerminalNum()) && !clientSocket.getTerminalNum().equals("null")) {
                                        //结束充电命令  05
                                        //端口号，订单号,故障信息（一个字节）
                                        String orderData = String.format("%02d", chargerOrder.getDevicePointIndex());
                                        String orderParam = "MS05" + chargerOrder.getDeviceSn() + orderData + "ME";
                                        System.out.println("结束充电命令: " + orderParam);
                                        clientSocket.getChannel().writeAndFlush(orderParam);
                                    }
                                }

                                //停止充电  充电结束
                                //充电状态 0 - 未充电 1 - 充电中 2 - 发起充电命令   3 - 充电已完成
                                chargerOrder.setChargerState(2);
                                portRecord.setRemark("涓流状态,结束充电中");
                                chargerOrder.setRemark("涓流状态,结束充电中");
                            }
                        }
                    }

                    /////////////////////余额不足，停止充电///////////////////
                    ret = chargerOrderMapper.updateById(chargerOrder);

                    portRecord.setTotalPrice(new BigDecimal(0));
                    ret = portRecordMapper.insert(portRecord);
                }
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        return ret;
    }


    @Override
    @Transactional
    public int addRecordByFree(Charger charger,int portIndex, String[] dataArray,String data,String orderNum) {
        int ret = 0;
        try{

            Parameter parameter = parameterService.getParameterById(1);
            //状态,电压,电流,订单号,功率
            //0,   1,   2,  3,    4
            ChargerPortRecord portRecord = new ChargerPortRecord();
            portRecord.setOrderNum(orderNum);
            portRecord.setChargerId(charger.getId());
            portRecord.setCreateTime(new Date());
            portRecord.setChargerNum(charger.getChargerNum());
            portRecord.setChargerSn(charger.getChargerSn());
            portRecord.setChargerPort(portIndex);
            portRecord.setOrderNo(dataArray[3]);
            portRecord.setDataStr(data);
            //电流
            if(StrUtil.isNotEmpty(dataArray[2])){
                double electricCurrent = MathUtil.getDoubleUp(Double.parseDouble(dataArray[2]) / 1000);
                portRecord.setElectricCurrent(electricCurrent);
            }
            //电压
            if(StrUtil.isNotEmpty(dataArray[1])){
                double voltage = MathUtil.getDoubleUp(Double.parseDouble(dataArray[1]) / 100);
                portRecord.setVoltage(voltage);
            }
            // 功率
            if(StrUtil.isNotEmpty(dataArray[4])){
                double power = MathUtil.getDoubleUp(portRecord.getElectricCurrent().doubleValue() * portRecord.getVoltage().doubleValue());
                if(charger.getAddPower()!=null && charger.getAddPower() > 0){
                    power += charger.getAddPower();
                }
                portRecord.setPower(power);
            }

            String key = "charger_" + charger.getChargerSn();
            charger.setLastOnlineTime(new Date());
            redisTemplate.opsForHash().put(key, key, JSONUtil.toJsonStr(charger));
            chargerMapper.updateById(charger);

            //带订单号的信条数据
            if(StrUtil.isNotEmpty(dataArray[3])) {
                ChargerOrder chargerOrder = chargerOrderMapper.selectOneByColumn("order_no",dataArray[3]);
                if(chargerOrder != null){

                    Map<String,Object> map = new HashMap<>();
                    map.put("charger_port_record", chargerOrder.getRecordTableName());
                    RequestDataHelper.setRequestData(map);

                    portRecord.setUserId(chargerOrder.getUserId());
                    int useMinutes = chargerOrder.getUseMinutes();
                    useMinutes = useMinutes + 1;
                    chargerOrder.setUseMinutes(useMinutes);
                    chargerOrder.setLastActiveTime(new Date());

                    //已经充电的度数
                    double chargerCapacity = getChargerCapacity(chargerOrder);
                    chargerOrder.setUseChargerCapacity(MathUtil.getDoubleUp(chargerCapacity));
                    //当前已经使用的钱
                    double useTotalPrice = 0d;
                    if(chargerOrder.getChargerRoleType() == 0){
                        useTotalPrice = getTotalPriceByCharger(chargerOrder);
                    }else if(chargerOrder.getChargerRoleType() == 1){
                        useTotalPrice = getTotalPriceByChargerType1(chargerOrder,chargerCapacity);
                    }else if(chargerOrder.getChargerRoleType() == 2){
                        useTotalPrice = getTotalPriceByChargerType2(chargerOrder);
                    }
                    int buyMinutes = chargerOrder.getBuyMinutes().intValue();
//                    useTotalPrice = MathUtil.getDoubleUp(useTotalPrice);
                    chargerOrder.setUsePrice(new BigDecimal(useTotalPrice));

                    double everyMin =  1.00 / 60.00 / 1000 *  portRecord.getPower();
                    portRecord.setChargerCapacity(new BigDecimal(everyMin));

                    //当前功率下的单价
                    portRecord.setPowerRoleId(0);
                    portRecord.setSinglePrice(new BigDecimal(0));
                    ChargerPowerRole powerRole = powerRoleService.getSinglePriceByChargerPower(charger, portRecord.getPower().doubleValue());
                    if(powerRole!=null){
                        portRecord.setPowerRoleId(powerRole.getId());
                        portRecord.setSinglePrice(powerRole.getSinglePriceHour());
                    }

                    /////////////////////余额不足，停止充电///////////////////
                    //如果是超过了当前支付的费用 要停止充电
                    if(chargerOrder.getChargerRoleType() == 0 && useTotalPrice>= chargerOrder.getPayPrice().doubleValue()){
                        List<ClientSocket> clientSocketList = SocketPool.getClientByDeviceNum(chargerOrder.getDeviceSn());
                        for (ClientSocket clientSocket : clientSocketList) {
                            if (StrUtil.isNotEmpty(clientSocket.getTerminalNum()) && !clientSocket.getTerminalNum().equals("null")) {
                                //结束充电命令  05
                                //端口号，订单号,故障信息（一个字节）
                                String orderData = String.format("%02d", chargerOrder.getDevicePointIndex());
                                String orderParam = "MS05" + chargerOrder.getDeviceSn() + orderData + "ME";
                                System.out.println("结束充电命令: " + orderParam);
                                clientSocket.getChannel().writeAndFlush(orderParam);
                            }
                        }
                        //停止充电  充电结束
                        //充电状态 0 - 未充电 1 - 充电中 2 - 发起充电命令   3 - 充电已完成
                        chargerOrder.setChargerState(2);
                        portRecord.setRemark("时间到");
                        chargerOrder.setRemark("时间到");
                    }
                    /////////////////////余额不足，停止充电///////////////////
                    //如果是超过了当前支付的费用 要停止充电
                    //判断度数， 已使用的是否超过购买的度数
                    else if(chargerOrder.getChargerRoleType() == 1 &&  chargerCapacity>= chargerOrder.getBuyChargerCapacity()){
                        List<ClientSocket> clientSocketList = SocketPool.getClientByDeviceNum(chargerOrder.getDeviceSn());
                        for (ClientSocket clientSocket : clientSocketList) {
                            if (StrUtil.isNotEmpty(clientSocket.getTerminalNum()) && !clientSocket.getTerminalNum().equals("null")) {
                                //结束充电命令  05
                                //端口号，订单号,故障信息（一个字节）
                                String orderData = String.format("%02d", chargerOrder.getDevicePointIndex());
                                String orderParam = "MS05" + chargerOrder.getDeviceSn() + orderData + "ME";
                                System.out.println("结束充电命令: " + orderParam);
                                clientSocket.getChannel().writeAndFlush(orderParam);
                            }
                        }
                        //停止充电  充电结束
                        //充电状态 0 - 未充电 1 - 充电中 2 - 发起结束充电命令   3 - 充电已完成
                        chargerOrder.setChargerState(2);
                        portRecord.setRemark("余额不足，结束充电中");
                        chargerOrder.setRemark("余额不足，结束充电中");
                    }
                    // 按照充电时间来算   购买的时间数  和 已经使用的 时间数
                    else if(chargerOrder.getChargerRoleType() == 2 && useMinutes >= buyMinutes){
                        List<ClientSocket> clientSocketList = SocketPool.getClientByDeviceNum(chargerOrder.getDeviceSn());
                        for (ClientSocket clientSocket : clientSocketList) {
                            if (StrUtil.isNotEmpty(clientSocket.getTerminalNum()) && !clientSocket.getTerminalNum().equals("null")) {
                                //结束充电命令  05
                                //端口号，订单号,故障信息（一个字节）
                                String orderData = String.format("%02d", chargerOrder.getDevicePointIndex());
                                String orderParam = "MS05" + chargerOrder.getDeviceSn() + orderData + "ME";
                                System.out.println("结束充电命令: " + orderParam);
                                clientSocket.getChannel().writeAndFlush(orderParam);
                            }
                        }
                        //停止充电  充电结束
                        //充电状态 0 - 未充电 1 - 充电中 2 - 发起结束充电命令   3 - 充电已完成
                        chargerOrder.setChargerState(2);
                        portRecord.setRemark("充电时间已到，结束充电");
                        chargerOrder.setRemark("充电时间已到，结束充电");
                    }
                    else{
                        //当前是正常继续进行
                        portRecord.setRemark("继续充电");
                        Date startChargerTime = chargerOrder.getStartChargerTime();
                        //{天, 时, 分, 秒}
                        long[] times = DateUtil.getDistanceTimes(startChargerTime,new Date());
                        //充电超过1小时20分钟 并且 功率小于50W的情况下 判断涓流
                        if(times[1] > 0 && portRecord.getPower() < 50){
                            //判断涓流算法
                            int lastLimitMin = 239;
                            if(powerRole!=null && powerRole.getLimitMin() !=null && powerRole.getLimitMin() > 0){
                                lastLimitMin = powerRole.getLimitMin();
                            }
                            List<Double> powerList = getAllRecordPowers(chargerOrder,lastLimitMin);
                            powerList.add(portRecord.getPower());
                            String ss = "";
                            for (Double d : powerList){
                                ss += d+ ",";
                            }
                            portRecord.setSlopePoints(ss);
                            double slope = MathUtil.getPowerSlope(powerList);
                            portRecord.setSlope(slope);
//                            System.out.println("最后60条记录斜率：" + slope);

                            List<Double> powerListLast10 = getAllRecordPowers(chargerOrder,29);
                            powerListLast10.add(portRecord.getPower());
                            String ss10 = "";
                            for (Double d : powerListLast10){
                                ss10 += d+ ",";
                            }
                            portRecord.setSlopePointsTen(ss10);
                            double slope10 = MathUtil.getPowerSlope(powerListLast10);
                            portRecord.setSlopeLastTen(slope10);
//                            System.out.println("最后10条记录斜率：" + slope10);

                            //已进入 涓流状态
                            if(slope <= 0.15 && slope10 <= 0.15){
                                List<ClientSocket> clientSocketList = SocketPool.getClientByDeviceNum(chargerOrder.getDeviceSn());
                                for (ClientSocket clientSocket : clientSocketList) {
                                    if (StrUtil.isNotEmpty(clientSocket.getTerminalNum()) && !clientSocket.getTerminalNum().equals("null")) {
                                        //结束充电命令  05
                                        //端口号，订单号,故障信息（一个字节）
                                        String orderData = String.format("%02d", chargerOrder.getDevicePointIndex());
                                        String orderParam = "MS05" + chargerOrder.getDeviceSn() + orderData + "ME";
                                        System.out.println("结束充电命令: " + orderParam);
                                        clientSocket.getChannel().writeAndFlush(orderParam);
                                    }
                                }

                                //停止充电  充电结束
                                //充电状态 0 - 未充电 1 - 充电中 2 - 发起充电命令   3 - 充电已完成
                                chargerOrder.setChargerState(2);
                                portRecord.setRemark("涓流状态,结束充电中");
                                chargerOrder.setRemark("涓流状态,结束充电中");
                            }
                        }
                    }

                    /////////////////////余额不足，停止充电///////////////////
                    ret = chargerOrderMapper.updateById(chargerOrder);

                    portRecord.setTotalPrice(new BigDecimal(0));
                    ret = portRecordMapper.insert(portRecord);
                }
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        return ret;
    }

    @Override
    @Transactional
    public int validateChargerOrder(Charger charger, int portIndex, String[] dataArray,String data,String orderNum) {
        int ret = 0;
        try{
            ChargerPort chargerPort = chargerPortService.getPortByChargerAndPort(charger,portIndex);
            if(chargerPort != null){
                if(StrUtil.isNotEmpty(chargerPort.getOrderNo())){
                    ChargerOrder chargerOrder = chargerOrderService.getOrderByOrderNo(chargerPort.getOrderNo());
                    if(chargerOrder != null){
                        int leftMinutes = chargerOrder.getBuyMinutes() - chargerOrder.getUseMinutes();
                        //如果当前还是在充电的状态
                        if(chargerOrder.getChargerState() == 1){
                            //  发送继续充电的 命令
                            List<ClientSocket> clientSocketList = SocketPool.getClientByDeviceNum(chargerOrder.getDeviceSn());
                            for (ClientSocket clientSocket : clientSocketList) {
                                if (StrUtil.isNotEmpty(clientSocket.getTerminalNum()) && !clientSocket.getTerminalNum().equals("null")) {
                                    //端口号,充电时间,订单编号
                                    String orderData = String.format("%02d", chargerOrder.getDevicePointIndex()) + "," + leftMinutes + ","+ chargerOrder.getOrderNo().toUpperCase();
                                    String orderParam = "MS10" + chargerOrder.getDeviceSn() + "" + orderData + "ME";
                                    System.out.println("开始充电命令: " + orderParam);
                                    clientSocket.getChannel().writeAndFlush(orderParam);
                                }
                            }
                        }
                        String key = "charger_" + charger.getChargerSn();
                        charger.setLastOnlineTime(new Date());
                        redisTemplate.opsForHash().put(key, key, JSONUtil.toJsonStr(charger));
                        chargerMapper.updateById(charger);
                    }
                }
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        return ret;
    }

    @Override
    public List<ChargerPortRecord> getAllRecordByOrderNo(ChargerOrder chargerOrder) {
        Map<String,Object> map = new HashMap<>();
        map.put("charger_port_record", chargerOrder.getRecordTableName());
        RequestDataHelper.setRequestData(map);

        QueryWrapper<ChargerPortRecord> qw = new QueryWrapper<>();
        qw.eq("order_no",chargerOrder.getOrderNo().toUpperCase());
        qw.eq("order_num","01");
        qw.orderByAsc("create_time");
        List<ChargerPortRecord> list = portRecordMapper.selectList(qw);
        return list;
    }

    @Override
    public List<ChargerPortRecord> getAllRecordByOrderNoGroupByPowerRole(ChargerOrder chargerOrder) {
        Map<String,Object> map = new HashMap<>();
        map.put("charger_port_record", chargerOrder.getRecordTableName());
        RequestDataHelper.setRequestData(map);

        QueryWrapper<ChargerPortRecord> qw = new QueryWrapper<>();
        qw.select(" ifnull(count(id) ,0) as count,single_price,power_role_id,power");
        qw.eq("order_no",chargerOrder.getOrderNo().toUpperCase());
        qw.eq("order_num","01");
        qw.groupBy("power_role_id");
        List<ChargerPortRecord> list = portRecordMapper.selectList(qw);
        return list;
    }

    @Override
    public List<Double> getAllRecordPowers(ChargerOrder chargerOrder, int lastLimit) {
        List<Double> powersNew = new ArrayList<>();
        List<Double> powers = new ArrayList<>();
        List<ChargerPortRecord> records = getAllRecordByOrderNo(chargerOrder);
        if(CollUtil.isNotEmpty(records)){
            for (ChargerPortRecord portRecord : records){
                powers.add(portRecord.getPower());
            }
        }

        if(lastLimit == 0){
            powersNew.addAll(powers);
        }else{
            int startIndex = powers.size() - lastLimit;
            int index = 0;
            for (Double power : powers){
                if(index >= startIndex){
                    powersNew.add(power);
                }
                index ++;
            }
        }
        return powersNew;
    }

    @Override
    @Transactional
    public int startCharger(Charger charger, String[] dataArray, String data) {
        int ret = 0 ;
        try{
            if(StrUtil.isNotEmpty(dataArray[2])) {
                ChargerOrder chargerOrder = chargerOrderMapper.selectOneByColumn("order_no", dataArray[2]);
                if (chargerOrder != null) {
                    if(dataArray[1].equals("1")){//成功
//                        chargerOrder.setEndChargerTime(new Date());
                        Map<String, Object> map = new HashMap<>();
                        map.put("charger_port_record", chargerOrder.getRecordTableName());
                        RequestDataHelper.setRequestData(map);

                        //如果第一次开启  设置开始时间
                        if(chargerOrder.getStartChargerTime() == null){
                            chargerOrder.setStartChargerTime(new Date());
                            chargerOrder.setChargerState(1);
                        }else{//如果终端断开 再次开启 设置更新时间
                            chargerOrder.setUpdateChargerTime(new Date());
                        }
                        chargerOrder.setStatus(3);
                        boolean bl = chargerOrderService.updateById(chargerOrder);
                        if(bl){
                            ret = 1;
                        }

                        ChargerPort port = chargerPortService.getPortByChargerIdAndPort(charger.getId(),chargerOrder.getDevicePointIndex());
                        if(port != null){
                            port.setState(1);
                            port.setOrderNo(dataArray[2]);
                            port.setStartTime(new Date());
                            port.setOrderTime(new Date());
                            chargerPortService.updateById(port);
                        }
                    }else{
                        //失败，发起退款
                        //计算 当前订单所有的 记录的 使用功率的 单价 和时间
//                        double useTotalPrice = getTotalPriceByCharger(chargerOrder);
//                        chargerOrder.setUsePrice(new BigDecimal(useTotalPrice));
                        //已经充电的度数
                        double chargerCapacity = getChargerCapacity(chargerOrder);
                        chargerOrder.setUseChargerCapacity(MathUtil.getDoubleUp(chargerCapacity));
                        //当前已经使用的钱
                        double useTotalPrice = 0d;
                        if(chargerOrder.getChargerRoleType() == 0){
                            useTotalPrice = getTotalPriceByCharger(chargerOrder);
                        }else if(chargerOrder.getChargerRoleType() == 1){
                            useTotalPrice = getTotalPriceByChargerType1(chargerOrder,chargerCapacity);
                        }else if(chargerOrder.getChargerRoleType() == 2){
                            useTotalPrice = getTotalPriceByChargerType2(chargerOrder);
                        }
//                        useTotalPrice = MathUtil.getDoubleUp(useTotalPrice);
                        chargerOrder.setUsePrice(new BigDecimal(useTotalPrice));

                        Parameter parameter = parameterService.getParameterById(1);
                        PlatformPay platformPay = platformPayService.getDefaultAccount();
                        //充电状态 0 - 未充电 1 - 充电中 2 - 发起充电命令   3 - 充电已完成
                        chargerOrder.setChargerState(3);
//                        chargerOrder.setChargerRemark("");
//                        chargerOrder.setRemark("");
                        double leftMoney = MathUtil.getDoubleUp(chargerOrder.getTotalPrice().doubleValue() - useTotalPrice);
                        String out_refund_no = OrderUtil.getOrderNoByTimespan();
                        if(parameter.getChargerPayPlatform() == 1){
                            out_refund_no = platformPay.getSysCode() + OrderUtil.getOrderNoByTimespan();
                        }
                        chargerOrder.setRefundOutTradeNo(out_refund_no);

//                        Parameter parameter = parameterService.getParameterById(1);
                        //收费的充电,并且是微信支付  才发起退款
                        if(chargerOrder.getIsFree() == 0) {
                            if (chargerOrder.getPayType() == 0) {//微信支付 退款
                                if (chargerOrder.getRefundStatus() == 0 || chargerOrder.getRefundStatus() == 1) {
                                    if (leftMoney > 0) {
                                        String retRequest = "";
                                        if(chargerOrder.getPayPlatform() == 0) {
                                            WxAppPay wxAppPay = new WxAppPay(wx_refund_notify_url, secret, appid, mch_id, api_key);
                                            //String out_trade_no,BigDecimal totalAmount, BigDecimal refund_money,String out_refund_no,String certPath
                                            retRequest = wxAppPay.refundPayAPI(chargerOrder.getOutTradeNo(), chargerOrder.getPayPrice(), new BigDecimal(leftMoney), chargerOrder.getRefundOutTradeNo(), keyPath);
                                            System.out.println("微信支付退款响应: " + retRequest);
                                        } else {
                                            //String out_trade_no, BigDecimal refund_money, String out_refund_no,PlatformPay platformPay
                                            retRequest = platformPayService.refundOrder(chargerOrder.getOutTradeNo(), new BigDecimal(leftMoney),chargerOrder.getRefundOutTradeNo(),platformPay);
                                            System.out.println("农商行退款响应: " + retRequest);
                                        }

                                        chargerOrder.setRefundRespParam(retRequest);
                                        JSONObject jsonObject = JSONUtil.parseObj(retRequest);
                                        if (jsonObject != null) {
                                            String code = "";
                                            String msg = "";
                                            boolean bl = false;
                                            if(chargerOrder.getPayPlatform() == 0) {
                                                code = jsonObject.containsKey("code") ? jsonObject.getStr("code") : "";
                                                msg = jsonObject.containsKey("msg") ? jsonObject.getStr("msg") : "";

                                                if (code.equals("SUCCESS")) {
                                                    bl = true;
                                                }
                                            }else{
                                                code = jsonObject.getStr("errCode");
                                                msg = jsonObject.getStr("errMsg");
                                                String refundStatus = jsonObject.getStr("refundStatus");

                                                if (code.equals("SUCCESS") && refundStatus.equals("SUCCESS")) {
                                                    bl = true;
                                                }
                                            }

                                            if (bl) {
                                                chargerOrder.setRefundPrice(new BigDecimal(leftMoney));
                                                //订单状态 0 - 未支付   1 - 支付中  2 - 已支付  3 - 充电中  4 - 已发起退款  5 - 退款完成  6 - 退款失败  7 - 订单已完成（结束） 8 -  订单取消
                                                chargerOrder.setStatus(4);
                                                //0 未退款 1 申请中 2 已退款
                                                chargerOrder.setRefundStatus(1);
                                            } else {
                                                //订单状态 0 - 未支付   1 - 支付中  2 - 已支付  3 - 充电中  4 - 已发起退款  5 - 退款完成  6 - 退款失败  7 - 订单已完成（结束） 8 -  订单取消
                                                chargerOrder.setStatus(6);
                                                chargerOrder.setChargerState(3);
                                                //0 未退款 1 申请中 2 已退款  3 - 失败
                                                chargerOrder.setRefundStatus(3);
                                            }
                                            chargerOrder.setRefundReason(msg);
                                        }
                                    } else {
                                        chargerOrder.setStatus(7);
                                    }
                                }
                            } else {
                                chargerOrder.setStatus(7);
                                chargerOrder.setRefundStatus(2);
                                if(leftMoney > 0){
                                    chargerOrder.setRefundPrice(new BigDecimal(leftMoney));
                                    // 退回剩余金额到 余额里面去
                                    SplitAccount splitAccount = splitAccountService.getAccountByUserId(chargerOrder.getUserId(),4,chargerOrder.getUserId());
                                    if(splitAccount != null){
                                        double chargerMoney = splitAccount.getChargerMoney().doubleValue();
                                        chargerMoney = chargerMoney + leftMoney;
                                        splitAccount.setChargerMoney(new BigDecimal(chargerMoney));
                                        boolean bl = splitAccountService.updateById(splitAccount);
                                        if(!bl){
                                            throw new TransactionalException("splitAccountService updateById error");
                                        }

                                        SplitAccountRecord accountRecord = new SplitAccountRecord();
                                        accountRecord.setUserId(chargerOrder.getUserId());
                                        accountRecord.setCreateTime(new Date());
                                        accountRecord.setAccountId(splitAccount.getId());
                                        accountRecord.setInOrOut(1);//进账
                                        accountRecord.setSplitMoney(new BigDecimal(leftMoney));
                                        accountRecord.setRemark("充电退款到账户");
                                        accountRecord.setFromType(7);
                                        splitAccountRecordService.save(accountRecord);
                                    }
                                }

                                ChargerPort port = chargerPortService.getPortByChargerIdAndPort(chargerOrder.getDeviceId(),chargerOrder.getDevicePointIndex());
                                if(port != null){
                                    port.setState(0);
                                    port.setOrderNo("");
                                    chargerPortService.updateById(port);
                                }
                            }
                        } else {
                            chargerOrder.setStatus(7);
                            ChargerPort port = chargerPortService.getPortByChargerIdAndPort(chargerOrder.getDeviceId(),chargerOrder.getDevicePointIndex());
                            if(port != null){
                                port.setState(0);
                                port.setOrderNo("");
                                chargerPortService.updateById(port);
                            }
                        }

                        ret = chargerOrderMapper.updateById(chargerOrder);
                        if(ret <= 0){
                            throw new TransactionalException("chargerOrderMapper updateById error");
                        }
                        wxTemplateService.sendWxMsgEndCharger(chargerOrder);
                    }
                }
            }

        }catch (Exception e){
            e.printStackTrace();
        }
        return ret;
    }


    @Override
    @Transactional
    public int overTask(Charger charger, String[] dataArray, String data) {
        int ret = 0;
        try{
            PlatformPay platformPay = platformPayService.getDefaultAccount();
//            Parameter parameter = parameterService.getParameterById(1);

            if(StrUtil.isNotEmpty(dataArray[1])){
                ChargerOrder chargerOrder = chargerOrderMapper.selectOneByColumn("order_no",dataArray[1]);
                if(chargerOrder!=null){
                    chargerOrder.setEndChargerTime(new Date());
                    Map<String,Object> map = new HashMap<>();
                    map.put("charger_port_record", chargerOrder.getRecordTableName());
                    RequestDataHelper.setRequestData(map);
                    //MS 05 12000014 00,00000001652362401153,,ME
                    //01,20位订单编号,01
                    //00,00000001652362401153,,
                    //00,00000001652958610341,,

                    int portIndex = Integer.parseInt(dataArray[0]) + 1;
                    ChargerPort chargerPort = chargerPortService.getPortByChargerAndPort(charger,portIndex);
                    if(chargerPort != null){
                        //修改 结束充电的状态
                        chargerPort.setState(0);
                        chargerPort.setOrderNo("");
                        chargerPort.setOrderTime(null);
                        boolean bl = chargerPortService.updateById(chargerPort);
                        if(!bl){
                            throw new TransactionalException("chargerPortService updateById error");
                        }
                    }
                    String errorCode = "";
                    if(dataArray.length >= 3){
                        errorCode = dataArray[2];
                    }


                    ChargerPortRecord portRecord = new ChargerPortRecord();
                    portRecord.setOrderNum("05");
                    portRecord.setChargerId(charger.getId());
                    portRecord.setCreateTime(new Date());
                    portRecord.setChargerNum(charger.getChargerNum());
                    portRecord.setChargerSn(charger.getChargerSn());
                    portRecord.setChargerPort(portIndex);
                    portRecord.setOrderNo(dataArray[1]);
                    portRecord.setDataStr(data);


                    if(dataArray.length == 5){
                        portRecord.setStopCode(dataArray[4]);
                        if(dataArray[4].equals("1") ){
                            portRecord.setStopMsg("充电时间结束停止充电");
                        } else if(dataArray[4].equals("2") ){
                            portRecord.setStopMsg("服务主动停止");
                        } else if(dataArray[4].equals("3") ){
                            portRecord.setStopMsg("功率过小停止充电");
                        } else if(dataArray[4].equals("4") ){
                            portRecord.setStopMsg("功率过大停止充电");
                        } else if(dataArray[4].equals("5") ){
                            portRecord.setStopMsg("硬件故障停止充电");
                        }
                    }

                    if(StrUtil.isEmpty(errorCode)){
                        portRecord.setRemark("充电结束");
                    }else{
                        portRecord.setRemark(getErrorCodeMsg(errorCode));
                    }
                    portRecord.setTotalPrice(new BigDecimal(0));
                    //当前功率下的单价
                    portRecord.setPowerRoleId(0);
                    portRecord.setSinglePrice(new BigDecimal(0));
                    ret = portRecordMapper.insert(portRecord);
                    if(ret <= 0){
                        throw new TransactionalException("portRecordMapper updateById error");
                    }

                    //计算 当前订单所有的 记录的 使用功率的 单价 和时间
//                    double useTotalPrice = getTotalPriceByCharger(chargerOrder);
//                    chargerOrder.setUsePrice(new BigDecimal(useTotalPrice));


                    //已经充电的度数
                    double chargerCapacity = getChargerCapacity(chargerOrder);
                    chargerOrder.setUseChargerCapacity(MathUtil.getDoubleUp(chargerCapacity));

                    //当前已经使用的钱
                    double useTotalPrice = 0d;
                    if(chargerOrder.getChargerRoleType() == 0){
                        useTotalPrice = getTotalPriceByCharger(chargerOrder);
                    }else if(chargerOrder.getChargerRoleType() == 1){
                        useTotalPrice = getTotalPriceByChargerType1(chargerOrder,chargerCapacity);
                    }else if(chargerOrder.getChargerRoleType() == 2){
                        useTotalPrice = getTotalPriceByChargerType2(chargerOrder);
                    }
//                    useTotalPrice = MathUtil.getDoubleUp(useTotalPrice);
                    chargerOrder.setUsePrice(new BigDecimal(useTotalPrice));

                    //充电状态 0 - 未充电 1 - 充电中 2 - 发起充电命令   3 - 充电已完成
                    chargerOrder.setChargerState(3);
                    chargerOrder.setChargerRemark("充电结束");
                    portRecord.setUserId(chargerOrder.getUserId());
                    //收费的充电,并且是微信支付  才发起退款
                    if(chargerOrder.getIsFree() == 0){
                        //
                        double leftMoney = MathUtil.getDoubleUp(chargerOrder.getTotalPrice().doubleValue() - useTotalPrice);
                        if(chargerOrder.getPayType() == 0){//微信支付 退款
                            if(chargerOrder.getRefundStatus() == 0 || chargerOrder.getRefundStatus() == 1){
                                String out_refund_no = OrderUtil.getOrderNoByTimespan();
                                if(chargerOrder.getPayPlatform() == 1) {
                                    out_refund_no = platformPay.getSysCode() + OrderUtil.getOrderNoByTimespan();
                                }
                                chargerOrder.setRefundOutTradeNo(out_refund_no);
                                if(leftMoney > 0){
                                    String retRequest = "";
                                    if(chargerOrder.getPayPlatform() == 0) {
                                        WxAppPay wxAppPay = new WxAppPay(wx_refund_notify_url, secret, appid, mch_id, api_key);
                                        //String out_trade_no,BigDecimal totalAmount, BigDecimal refund_money,String out_refund_no,String certPath
                                        retRequest = wxAppPay.refundPayAPI(chargerOrder.getOutTradeNo(), chargerOrder.getPayPrice(), new BigDecimal(leftMoney), chargerOrder.getRefundOutTradeNo(), keyPath);
                                        System.out.println("微信支付退款响应: " + retRequest);
                                    } else {
                                        //String out_trade_no, BigDecimal refund_money, String out_refund_no,PlatformPay platformPay
                                        retRequest = platformPayService.refundOrder(chargerOrder.getOutTradeNo(), new BigDecimal(leftMoney),chargerOrder.getRefundOutTradeNo(),platformPay);
                                        System.out.println("农商行退款响应: " + retRequest);
                                    }

                                    chargerOrder.setRefundRespParam(retRequest);

                                    JSONObject jsonObject = JSONUtil.parseObj(retRequest);
                                    if(jsonObject!=null){
                                        String code = "";
                                        String msg = "";
                                        boolean bl = false;
                                        if(chargerOrder.getPayPlatform() == 0) {
                                            code = jsonObject.containsKey("code") ? jsonObject.getStr("code") : "";
                                            msg = jsonObject.containsKey("msg") ? jsonObject.getStr("msg") : "";

                                            if (code.equals("SUCCESS")) {
                                                bl = true;
                                            }
                                        }else{
                                            code = jsonObject.getStr("errCode");
                                            msg = jsonObject.getStr("errMsg");
                                            String refundStatus = jsonObject.getStr("refundStatus");
                                            if (code.equals("SUCCESS") && refundStatus.equals("SUCCESS")) {
                                                bl = true;
                                            }
                                        }

                                        if (bl) {
                                            chargerOrder.setRefundPrice(new BigDecimal(leftMoney));
                                            //订单状态 0 - 未支付   1 - 支付中  2 - 已支付  3 - 充电中  4 - 已发起退款  5 - 退款完成  6 - 退款失败  7 - 订单已完成（结束） 8 -  订单取消
                                            chargerOrder.setStatus(4);
                                            //0 未退款 1 申请中 2 已退款
                                            chargerOrder.setRefundStatus(1);
                                        }else{
                                            //订单状态 0 - 未支付   1 - 支付中  2 - 已支付  3 - 充电中  4 - 已发起退款  5 - 退款完成  6 - 退款失败  7 - 订单已完成（结束） 8 -  订单取消
                                            chargerOrder.setStatus(6);
                                            chargerOrder.setChargerState(3);
                                            //0 未退款 1 申请中 2 已退款  3 - 失败
                                            chargerOrder.setRefundStatus(3);
                                        }
                                        chargerOrder.setRefundReason(msg);
                                    }
                                }else{
                                    chargerOrder.setStatus(7);
                                }
                            }
                        }else if(chargerOrder.getPayType() == 1){ //余额支付
                            chargerOrder.setStatus(7);
                            chargerOrder.setRefundStatus(2);
                            if(leftMoney > 0){
                                chargerOrder.setRefundPrice(new BigDecimal(leftMoney));

                                // 退回剩余金额到 余额里面去
                                SplitAccount splitAccount = splitAccountService.getAccountByUserId(chargerOrder.getUserId(),4,chargerOrder.getUserId());
                                if(splitAccount != null){
                                    double chargerMoney = splitAccount.getChargerMoney().doubleValue();
                                    chargerMoney = chargerMoney + leftMoney;
                                    splitAccount.setChargerMoney(new BigDecimal(chargerMoney));
                                    boolean bl = splitAccountService.updateById(splitAccount);
                                    if(!bl){
                                        throw new TransactionalException("splitAccountService updateById error");
                                    }

                                    SplitAccountRecord accountRecord = new SplitAccountRecord();
                                    accountRecord.setUserId(chargerOrder.getUserId());
                                    accountRecord.setCreateTime(new Date());
                                    accountRecord.setAccountId(splitAccount.getId());
                                    accountRecord.setInOrOut(1);//进账
                                    accountRecord.setSplitMoney(new BigDecimal(leftMoney));
                                    accountRecord.setRemark("充电退款到账户");
                                    accountRecord.setFromType(7);
                                    splitAccountRecordService.save(accountRecord);
                                }
                            }

                            ChargerPort port = chargerPortService.getPortByChargerIdAndPort(chargerOrder.getDeviceId(),chargerOrder.getDevicePointIndex());
                            if(port != null){
                                port.setState(0);
                                port.setOrderNo("");
                                chargerPortService.updateById(port);
                            }
                        }
                    }else{
                        chargerOrder.setStatus(7);

                        ChargerPort port = chargerPortService.getPortByChargerIdAndPort(chargerOrder.getDeviceId(),chargerOrder.getDevicePointIndex());
                        if(port != null){
                            port.setState(0);
                            port.setOrderNo("");
                            chargerPortService.updateById(port);
                        }
                    }
                    ret = chargerOrderMapper.updateById(chargerOrder);
                    if(ret <= 0){
                        throw new TransactionalException("chargerOrderMapper updateById error");
                    }
                    wxTemplateService.sendWxMsgEndCharger(chargerOrder);
                }
            }
        }catch (Exception e){
            e.printStackTrace();
            throw new TransactionalException("overTask updateById error");
        }
        return ret;
    }


    @Override
    @Transactional
    public int overTaskByOrderNo(ChargerOrder chargerOrder) {
        int ret = 0;
        try{
            PlatformPay platformPay = platformPayService.getDefaultAccount();
//            Parameter parameter = parameterService.getParameterById(1);
            if(chargerOrder!=null){
                chargerOrder.setEndChargerTime(new Date());

                Map<String,Object> map = new HashMap<>();
                map.put("charger_port_record", chargerOrder.getRecordTableName());
                RequestDataHelper.setRequestData(map);

                Charger charger = chargerMapper.selectById(chargerOrder.getDeviceId());
                if(charger == null){
                    throw new TransactionalException("chargerMapper selectById error");
                }

                int portIndex = chargerOrder.getDevicePointIndex();
                ChargerPort chargerPort = chargerPortService.getPortByChargerAndPort(charger,portIndex);
                if(chargerPort != null){
                    //修改 结束充电的状态
                    chargerPort.setState(0);
                    boolean bl = chargerPortService.updateById(chargerPort);
                    if(!bl){
                        throw new TransactionalException("chargerPortService updateById error");
                    }
                }

                //计算 当前订单所有的 记录的 使用功率的 单价 和时间
//                double useTotalPrice = getTotalPriceByCharger(chargerOrder);
//                chargerOrder.setUsePrice(new BigDecimal(useTotalPrice));


                //已经充电的度数
                double chargerCapacity = getChargerCapacity(chargerOrder);
                chargerOrder.setUseChargerCapacity(MathUtil.getDoubleUp(chargerCapacity));
                //当前已经使用的钱
                double useTotalPrice = 0d;
                if(chargerOrder.getChargerRoleType() == 0){
                    //按照功率来计算
                    useTotalPrice = getTotalPriceByCharger(chargerOrder);
                }else if(chargerOrder.getChargerRoleType() == 1){
                    //按照充电度数来计算
                    useTotalPrice = getTotalPriceByChargerType1(chargerOrder,chargerCapacity);
                }else if(chargerOrder.getChargerRoleType() == 2){
                    //按照时间来计算
                    useTotalPrice = getTotalPriceByChargerType2(chargerOrder);
                }
                chargerOrder.setUsePrice(new BigDecimal(useTotalPrice));

                //充电状态 0 - 未充电 1 - 充电中 2 - 发起充电命令   3 - 充电已完成
                chargerOrder.setChargerState(3);
                chargerOrder.setChargerRemark("设备异常离线，充电结束");
                //
                double leftMoney = MathUtil.getDoubleUp(chargerOrder.getTotalPrice().doubleValue() - useTotalPrice);

                String out_refund_no = OrderUtil.getOrderNoByTimespan();
                if(chargerOrder.getPayPlatform() == 1) {
                    out_refund_no = platformPay.getSysCode() + OrderUtil.getOrderNoByTimespan();
                }
                chargerOrder.setRefundOutTradeNo(out_refund_no);

                if(chargerOrder.getIsFree() == 0) {//  不免费的情况下
                    if(chargerOrder.getPayType() == 0) {//微信支付 退款
                        if(chargerOrder.getRefundStatus() == 0 || chargerOrder.getRefundStatus() == 1){
                            if(leftMoney > 0){
                                String retRequest = "";
                                if(chargerOrder.getPayPlatform() == 0) {
                                    WxAppPay wxAppPay = new WxAppPay(wx_refund_notify_url, secret, appid, mch_id, api_key);
                                    retRequest = wxAppPay.refundPayAPI(chargerOrder.getOutTradeNo(), chargerOrder.getPayPrice(), new BigDecimal(leftMoney), chargerOrder.getRefundOutTradeNo(), keyPath);
                                    System.out.println("微信支付退款响应: " + retRequest);
                                } else {
                                    retRequest = platformPayService.refundOrder(chargerOrder.getOutTradeNo(), new BigDecimal(leftMoney),chargerOrder.getRefundOutTradeNo(),platformPay);
                                    System.out.println("农商行退款响应: " + retRequest);
                                }
                                chargerOrder.setRefundRespParam(retRequest);

                                JSONObject jsonObject = JSONUtil.parseObj(retRequest);
                                if(jsonObject!=null){
                                    String code = "";
                                    String msg = "";
                                    boolean bl = false;
                                    if(chargerOrder.getPayPlatform() == 0) {
                                        code = jsonObject.containsKey("code") ? jsonObject.getStr("code") : "";
                                        msg = jsonObject.containsKey("msg") ? jsonObject.getStr("msg") : "";

                                        if (code.equals("SUCCESS")) {
                                            bl = true;
                                        }
                                    }else{
                                        code = jsonObject.getStr("errCode");
                                        msg = jsonObject.getStr("errMsg");
                                        String refundStatus = jsonObject.getStr("refundStatus");

                                        if (code.equals("SUCCESS") && refundStatus.equals("SUCCESS")) {
                                            bl = true;
                                        }
                                    }

                                    if (bl) {
                                        chargerOrder.setRefundPrice(new BigDecimal(leftMoney));
                                        //订单状态 0 - 未支付   1 - 支付中  2 - 已支付  3 - 充电中  4 - 已发起退款  5 - 退款完成  6 - 退款失败  7 - 订单已完成（结束） 8 -  订单取消
                                        chargerOrder.setStatus(4);
                                        //0 未退款 1 申请中 2 已退款
                                        chargerOrder.setRefundStatus(1);
                                    }else{
                                        //订单状态 0 - 未支付   1 - 支付中  2 - 已支付  3 - 充电中  4 - 已发起退款  5 - 退款完成  6 - 退款失败  7 - 订单已完成（结束） 8 -  订单取消
                                        chargerOrder.setStatus(6);
                                        chargerOrder.setChargerState(3);
                                        //0 未退款 1 申请中 2 已退款  3 - 失败
                                        chargerOrder.setRefundStatus(3);
                                    }
                                    chargerOrder.setRefundReason(msg);
                                }
                            }else{
                                chargerOrder.setStatus(7);
                            }
                        }
                    }else{
                        chargerOrder.setStatus(7);
                        chargerOrder.setRefundStatus(2);
                        if(leftMoney > 0){
                            chargerOrder.setRefundPrice(new BigDecimal(leftMoney));
                            // 退回剩余金额到 余额里面去
                            SplitAccount splitAccount = splitAccountService.getAccountByUserId(chargerOrder.getUserId(),4,chargerOrder.getUserId());
                            if(splitAccount != null){
                                double chargerMoney = splitAccount.getChargerMoney().doubleValue();
                                chargerMoney = chargerMoney + leftMoney;
                                splitAccount.setChargerMoney(new BigDecimal(chargerMoney));
                                boolean bl = splitAccountService.updateById(splitAccount);
                                if(!bl){
                                    throw new TransactionalException("splitAccountService updateById error");
                                }


                                SplitAccountRecord accountRecord = new SplitAccountRecord();
                                accountRecord.setUserId(chargerOrder.getUserId());
                                accountRecord.setCreateTime(new Date());
                                accountRecord.setAccountId(splitAccount.getId());
                                accountRecord.setInOrOut(1);//进账
                                accountRecord.setSplitMoney(new BigDecimal(leftMoney));
                                accountRecord.setRemark("充电退款到账户");
                                accountRecord.setFromType(7);
                                splitAccountRecordService.save(accountRecord);
                            }
                        }

                        ChargerPort port = chargerPortService.getPortByChargerIdAndPort(chargerOrder.getDeviceId(),chargerOrder.getDevicePointIndex());
                        if(port != null){
                            port.setState(0);
                            port.setOrderNo("");
                            chargerPortService.updateById(port);
                        }
                    }
                }else{
                    chargerOrder.setStatus(7);

                    ChargerPort port = chargerPortService.getPortByChargerIdAndPort(chargerOrder.getDeviceId(),chargerOrder.getDevicePointIndex());
                    if(port != null){
                        port.setState(0);
                        port.setOrderNo("");
                        chargerPortService.updateById(port);
                    }
                }

                ret = chargerOrderMapper.updateById(chargerOrder);
                if(ret <= 0){
                    throw new TransactionalException("chargerOrderMapper updateById error");
                }
                wxTemplateService.sendWxMsgEndCharger(chargerOrder);
            }
        }catch (Exception e){
            e.printStackTrace();
            throw new TransactionalException("overTask updateById error");
        }
        return ret;
    }

    private String getErrorCodeMsg(String code){
//        0->都没问题
//        1->检测通信故障
//        2 检测芯片未校准，数据不可用
//        3 检测通信故障且检测芯片未校准，数据不可用
//        4 芯片参数不可用
//        5 芯片参数不可用,检测通信故障
//        6 芯片参数不可用,检测芯片未校准，数据不可用
//        7 芯片参数不可用，检测通信故障且检测芯片未校准，数据不可用
//        8 功率过大
//        9 功率过大且检测通信故障
//        a  功率过大且芯片未校准
//        b 功率过大且通信故障且检测芯片未校准
//        c 功率过大且芯片参数不可用
//        d 功率过大且芯片参数不可用,检测通信故障
//        e 功率过大且芯片参数不可用,且检测芯片未校准
//        f 功率过大且芯片参数不可用,检测通信故障且检测芯片未校准，数据不可用
        switch (code.toLowerCase()){
            case "0" : return "";
            case "1" : return "检测通信故障";
            case "2" : return "检测芯片未校准，数据不可用";
            case "3" : return "检测通信故障且检测芯片未校准，数据不可用";
            case "4" : return "芯片参数不可用";
            case "5" : return "芯片参数不可用,检测通信故障";
            case "6" : return "芯片参数不可用,检测芯片未校准，数据不可用";
            case "7" : return "芯片参数不可用，检测通信故障且检测芯片未校准，数据不可用";
            case "8" : return "功率过大";
            case "9" : return "功率过大且检测通信故障";
            case "a" : return "功率过大且芯片未校准";
            case "b" : return "功率过大且通信故障且检测芯片未校准";
            case "c" : return "功率过大且芯片参数不可用";
            case "d" : return "功率过大且芯片参数不可用,检测通信故障";
            case "e" : return "功率过大且芯片参数不可用,且检测芯片未校准";
            case "f" : return "功率过大且芯片参数不可用,检测通信故障且检测芯片未校准，数据不可用";
        }
        return code;
    }


    /**
     *  获取当前订单已经使用的费用
     * @param chargerOrder
     * @return
     */
    private double getTotalPriceByCharger(ChargerOrder chargerOrder){
        double totalPrice = 0;
        List<ChargerPortRecord> list = getAllRecordByOrderNoGroupByPowerRole(chargerOrder);
        if(CollUtil.isNotEmpty(list)) {
            for (ChargerPortRecord record : list){
                // 分钟数
                int count = record.getCount();
                //每小时的单价
                double single_price = record.getSinglePrice().doubleValue();
                double price =  single_price  / 60 * count;
                totalPrice += price;
            }
        }
        return totalPrice;
    }


    /**
     * 获取当前订单已经使用的费用
     * @param chargerOrder
     * @param chargerCapacity
     * @return
     */
    private double getTotalPriceByChargerType1(ChargerOrder chargerOrder, double chargerCapacity){
        double totalPrice = 0;
        ChargerPowerRole powerRole = powerRoleService.getSinglePriceByChargerPower(chargerOrder.getDeviceId(),0);
        if(powerRole != null){
            totalPrice = chargerCapacity * powerRole.getChargerSinglePrice().doubleValue();
        }
        return totalPrice;
    }


    /**
     * 获取当前订单已经使用的费用
     * @param chargerOrder
     * @return
     */
    private double getTotalPriceByChargerType2(ChargerOrder chargerOrder){
        double totalPrice = 0;
        int useMinites = chargerOrder.getUseMinutes().intValue();
        totalPrice = useMinites * (chargerOrder.getTotalPrice().doubleValue() / chargerOrder.getBuyMinutes());
        return totalPrice;
    }

    /**
     *  获取当前订单的充电量
     * @param chargerOrder
     * @return
     */
    @Override
    public double getChargerCapacity(ChargerOrder chargerOrder){
        double capacity = 0d;
        Map<String,Object> map = new HashMap<>();
        map.put("charger_port_record", chargerOrder.getRecordTableName());
        RequestDataHelper.setRequestData(map);

        QueryWrapper<ChargerPortRecord> qw = new QueryWrapper<>();
        qw.eq("order_no",chargerOrder.getOrderNo().toUpperCase());
        qw.eq("order_num","01");
        List<ChargerPortRecord> list = portRecordMapper.selectList(qw);
        if(CollUtil.isNotEmpty(list)){
            for (ChargerPortRecord record : list){
                // 分钟数
//                int count = record.getCount();
                //每小时的单价
//                double single_price = record.getPower().doubleValue();
                // 1000 W / h = 0.55
                // 1000W / min = 0.0091666666666667
                // 1W / min =  0.00000916666666666
                // 1 / 60 = 1000w 每分钟的消耗度数
                //
                double everyMin =  1.00 / 60.00 / 1000 *  record.getPower();
//                System.out.println( "1.00 / 60.00 / 1000 * " + "" + record.getPower() + " = " + everyMin);
                capacity += everyMin;
            }
//            System.out.println("四舍五入前：" + capacity);
//            capacity = MathUtil.getDoubleUp(capacity);
//            System.out.println("四舍五入后：" + capacity);
        }
        return capacity;
    }
}
